import cpp

/*
 * Only calls to `snprintf` with `%s` in the format specifier
 * are likely to be vulnerable. This is because other format
 * specifiers, like `%d` can only change the length of the output
 * string by a few character, but `%s` can change it a lot.
 * A `%s` specifier is also much more likely to enable an attacker
 * to overwrite the stack or heap with working shellcode.
 */
from FunctionCall call
where call.getTarget().getName() = "snprintf"
and not call instanceof ExprInVoidContext
and call.getArgument(2).getValue().regexpMatch("(?s).*%s.*")
select call
